﻿#if NET45
using MessagePack;
using MessagePack.Formatters;
using MessagePack.Resolvers;
#endif
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Runtime.Serialization;
using System.Text;

namespace CNative.Utilities
{
    public class JsonHelper
    {
#if NET45
        static JsonHelper()
        {
            JsonSerializerSettings setting = new JsonSerializerSettings();
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //日期类型默认格式化处理
                setting.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                return setting;
            });
            var array = new IFormatterResolver[]
            {
                NativeDateTimeResolver.Instance,
                BuiltinResolver.Instance,
                AttributeFormatterResolver.Instance,
                DynamicEnumResolver.Instance,
                DynamicGenericResolver.Instance,
                DynamicUnionResolver.Instance,
                DynamicObjectResolver.Instance,
                DataSetFormatter.Instance,
                DynamicContractlessObjectResolver.Instance
            };
            CompositeResolver.RegisterAndSetAsDefault(array);
        }
#endif
        public static byte[] SerializeObject(object value)
        {
#if NET45
            if (value == null) return new byte[0];
            var bytes = MessagePack.MessagePackSerializer.NonGeneric.Serialize(value.GetType(), value);
            return bytes;
#else
            return UTF8Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));
#endif
        }


        public static object DeserializeObject(byte[] value, Type type)
        {
            if (value.Length == 0)
            {
                return null;
            }
#if NET45
            return MessagePack.MessagePackSerializer.NonGeneric.Deserialize(type, value);
#else
            return JsonConvert.DeserializeObject(UTF8Encoding.UTF8.GetString(value), type);
#endif
        }

        public static object DeserializeObjectByJson(string value, Type type)
        {
            //if (string.IsNullOrEmpty(value))
            //{
            //    return null;
            //}
            //var binary = MessagePack.MessagePackSerializer.FromJson(value);
            //return MessagePackSerializer.NonGeneric.Deserialize(type, binary);
            return JsonConvert.DeserializeObject(value, type);
        }
#if NET45
        public static byte[] ConvertJsonToBinary(string json)
        {
            return MessagePack.MessagePackSerializer.FromJson(json);
        }

        public static string ConvertBinaryToJson(byte[] value)
        {
            return MessagePack.MessagePackSerializer.ToJson(value);
        }
#endif

        public static T DeserializeObjectByJson<T>(string value)
        {
            return (T)DeserializeObjectByJson(value, typeof(T));
        }

        public static string SerializeObjectToJson(object value)
        {
            return JsonConvert.SerializeObject(value);
            //if (value == null) return null;
            //var bytes = MessagePack.MessagePackSerializer.NonGeneric.Serialize(value.GetType(), value);
            //var jsonString = MessagePackSerializer.ToJson(bytes);
            //return jsonString;
        }

        public static T DeserializeObject<T>(byte[] value)
        {
            //return JsonConvert.DeserializeObject<T>(value);
            return (T)DeserializeObject(value, typeof(T));
        }



    }
#if NET45
    public class DataSetFormatter : IFormatterResolver
    {
        public static IFormatterResolver Instance = new DataSetFormatter();
        public IMessagePackFormatter<T> GetFormatter<T>()
        {
            if (typeof(T) == typeof(DataSet) || typeof(T) == typeof(DataTable))
            {
                var msg = new DataSetPackFormatter<T>();
                var val = msg as IMessagePackFormatter<T>;
                return val;
            }
            else
            {
                return null;
            }
        }
    }

    public class DataSetPackFormatter<T> : IMessagePackFormatter<T>
    {
        public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
        {
            var serializer = new DataContractSerializer(typeof(T));
            if (typeof(T) == typeof(DataTable))
            {
                var dt = value as DataTable;
                if (dt != null && string.IsNullOrEmpty(dt.TableName))
                {
                    dt.TableName = "Table0";
                }
            }
            var stream = new MemoryStream();
            serializer.WriteObject(stream, value);
            bytes = stream.ToArray();
            return bytes.Length;
        }

        public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
        {
            readSize = 0;
            var serializer = new DataContractSerializer(typeof(T));
            var obj = serializer.ReadObject(new MemoryStream(bytes));
            return (T)obj;
        }

    }
#endif
}
